package com.sservice.service.service.impl;

import com.sservice.model.dao.ApplyPayBillMapper;
import com.sservice.model.dao.PurchaseOrderMapper;
import com.sservice.model.entity.ApplyPayBill;
import com.sservice.model.entity.PurchaseOrder;
import com.sservice.model.log.ApplyPayStatus;
import com.sservice.model.vo.ApplyPayBillVo;
import com.sservice.service.service.ExportService;
import com.sservice.service.service.IApplyPayBillService;
import com.sservice.base.entity.dto.ListResult;
import com.sservice.base.entity.dto.Pagination;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by suweiming on 2017/12/20.
 */

@Service
public class IApplyPayBillServiceImpl implements IApplyPayBillService {
    @Autowired
    ApplyPayBillMapper mapper;
    @Autowired
    PurchaseOrderMapper orderMapper;

    @Autowired
    ExportService exportService;

    @Override
    public Object create(ApplyPayBill apb) {
        PurchaseOrder po = orderMapper.selectByPrimaryKey(Integer.valueOf(apb.getOrderId()));
        if (po.getApplyPayTotal().add(apb.getTotal()).compareTo(po.getTotal()) == 1) {
            return "累计申请金额已超出订单金额，请查正后重新申请！";
        }
        ApplyPayBill apb1 = new ApplyPayBill();
        apb1.setOrderId(apb.getOrderId());
        apb1.setTotal(apb.getTotal());
        apb1.setPayTime(apb.getPayTime()); // 计划付款时间
        apb1.setApplier(apb.getApplier());
        apb1.setClienteleId(po.getClienteleId());
        apb1.setUnitCode(po.getUnitCode());
        apb1.setGoodsName(po.getGoodsName());
        apb1.setClienteleName(po.getClienteleName());
        apb1.setGoodsId(po.getGoodsId());
        apb1.setOrderNo(po.getNo());
        apb1.setUserName(apb.getUserName() + ":::");
        mapper.insertSelective(apb1);
        PurchaseOrder po1 = new PurchaseOrder();
        po1.setApplyPayTotal(po.getApplyPayTotal().add(apb.getTotal()));
        if (Double.compare(po.getActualReceiveTotal().add(po1.getApplyPayTotal()).doubleValue(),
                po.getTotal().doubleValue()) == 0) {
            po1.setApplyPay(ApplyPayStatus.ED.getIndex()); // 已付款
        } else {
            po1.setApplyPay(ApplyPayStatus.PART.getIndex()); // 部分付款
        }

        po1.setId(po.getId());
        orderMapper.updateByPrimaryKeySelective(po1);
        return apb1.getId();
    }

    /***
     *  采购付款申请单删除，此功能前置条件：
     *  1. 没有被出纳核算前有效
     * @param apb
     * @return
     */
    @Override
    public Object cancel(ApplyPayBill apb) {
        if (("0".equals(apb.getStatusCheck()) || "2".equals(apb.getStatusCheck())) && "0".equals(apb.getStatusHesuan()) && "0".equals(apb.getStatusPay())) {  //
            ApplyPayBill applyPayBill = mapper.selectByPrimaryKey(apb.getId()); //
            PurchaseOrder po = orderMapper.selectByPrimaryKey(Integer.valueOf(applyPayBill.getOrderId()));
            po.setApplyPayTotal(po.getApplyPayTotal().subtract(applyPayBill.getTotal())); // 扣减申请金额
            po.setApplyPay((BigDecimal.ZERO.compareTo(po.getApplyPayTotal()) == 0) ? "0" : "1");//
            orderMapper.updateByPrimaryKeySelective(po);
            return mapper.deleteByPrimaryKey(apb.getId());
        } else {
            return "申请单已经被核算，不能被删除!";
        }
    }


    @Override
    public ListResult page(ApplyPayBillVo apb) {
        List<ApplyPayBillVo> list = mapper.queryByPage(apb);
        int total = mapper.queryByCount(apb);
        Pagination page = new Pagination(apb.getPage(), total, apb.getSize());
        ListResult res = new ListResult(true, list);
        res.setPage(page);
        return res;
    }

    /**
     * 1. 采购付款申请单导出
     * 2. 采购已付明细
     *
     * @param apb
     * @return
     */
    @Override
    public OutputStream export(ApplyPayBillVo apb, HttpServletRequest request, HttpServletResponse response) {
        apb.setSize(Integer.MAX_VALUE);
        apb.setPage(0);
        boolean isVerified = false;
        if ("0".equals(apb.getType()) && BigDecimal.valueOf(1.0).equals(apb.getActual())) {
            isVerified = true;
        }
        List<ApplyPayBillVo> list = mapper.queryByPage(apb);
        ServletOutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }

        exportService.setResponseHeader(response, request, isVerified ? "采购已付明细" : "采购付款申请单Excel");
        String hql = isVerified ? "采购已付明细" : "采购付款申请单"; // sheet 名称

        List<Map> lm = new ArrayList<Map>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        if (isVerified) { // 采购已付明细导出
            for (int i = 0; i < list.size(); i++) {
                Map map = new LinkedHashMap();
                ApplyPayBillVo ov = list.get(i);
                map.put("采购订单号", ov.getNo());
                map.put("产品名称", ov.getGoodsName());
                map.put("采购数量", ov.getNumber());
                map.put("价格", ov.getCurrentPrice());
                map.put("订单金额", ov.getOrderTotal());
                map.put("申请付款", ov.getTotal());
                map.put("实付金额", ov.getActual());
                map.put("计划付款日期", sdf.format(ov.getPayTime()));
                map.put("供应商", ov.getClienteleName());
                map.put("是否已核算", "0".equals(ov.getStatusHesuan()) ? "未审核" : "已核算");
                map.put("是否已审核", "0".equals(ov.getStatusCheck()) ? "未审核" : ("1".equals(ov.getStatusCheck()) ? "审核通过" : "审核未通过"));
                map.put("订单状态", "0".equals(ov.getStatus()) ? "未执行" : ("1".equals(ov.getStatus()) ? "执行中" : ("2".equals(ov.getStatus()) ? "终止执行" : ("3".equals(ov.getStatus()) ? "强制执行完毕" : ("4".equals(ov.getStatus()) ? "执行完毕" : (""))))));
                map.put("备注", "");
                map.put("申请用户", ov.getUserName());
                map.put("申请时间", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(ov.getCreateAt()));
                lm.add(map);
            }
            return exportService.exportExcel(hql, lm, outputStream);
        } else if ("0".equals(apb.getType())) { // 采购付款申请单导出
            for (int i = 0; i < list.size(); i++) { //
                Map map = new LinkedHashMap();
                ApplyPayBillVo ov = list.get(i);
                map.put("采购订单号", ov.getNo());
                map.put("产品名称", ov.getGoodsName());
                map.put("采购数量", ov.getNumber());
                map.put("价格", ov.getCurrentPrice());
                map.put("订单金额", ov.getOrderTotal());
                map.put("申请付款", ov.getTotal());
                map.put("实付金额", ov.getActual());
                map.put("计划付款", sdf.format(ov.getPayTime()));
                map.put("供应商", ov.getClienteleName());
                map.put("是否已核算", "0".equals(ov.getStatusHesuan()) ? "未审核" : "已核算");
                map.put("是否已审核", "0".equals(ov.getStatusCheck()) ? "未审核" : ("1".equals(ov.getStatusCheck()) ? "审核通过" : "审核未通过"));
                map.put("订单状态", "0".equals(ov.getStatus()) ? "未执行" : ("1".equals(ov.getStatus()) ? "执行中" : ("2".equals(ov.getStatus()) ? "终止执行" : ("3".equals(ov.getStatus()) ? "强制执行完毕" : ("4".equals(ov.getStatus()) ? "执行完毕" : (""))))));
                map.put("备注", "");
                map.put("申请用户", ov.getUserName());
                map.put("申请时间", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(ov.getCreateAt()));
                lm.add(map);
            }
            return exportService.exportExcel(hql, lm, outputStream);
        }
        return null;
    }


    /**
     * 已付金额变化
     *
     * @param id
     * @param payed 负数表示退回，正数表示付出
     * @return
     */
    @Override
    public int changeNumber(Integer id, BigDecimal payed) {
        ApplyPayBill apb = mapper.selectByPrimaryKey(id);
        ApplyPayBill apb1 = new ApplyPayBill();
        apb1.setId(id);
        apb1.setActual(apb.getActual().add(payed));
        if (apb1.getActual().compareTo(apb.getTotal()) == -1 && apb1.getActual().compareTo(BigDecimal.ZERO) >= 0) {
            apb1.setStatusPay("0");
            apb1.setStatusCheck("0");
            apb1.setStatusHesuan("0");
            return mapper.updateByPrimaryKeySelective(apb1);
        } else {
            throw new RuntimeException("数据异常");
        }

    }
}

